program BlackSpace2;

uses
  SysUtils,
  Graphics,
  Dialogs,
  classes,
  ExtCtrls,
  Math,
  Gen2 in 'C:\Program Files (x86)\Embarcadero\Gen2_v1.4\Gen2.pas',
  G2Math in 'C:\Program Files (x86)\Embarcadero\Gen2_v1.4\G2Math.pas',
  G2Avi in 'C:\Program Files (x86)\Embarcadero\Gen2_v1.4\G2Avi.pas',
  G2MeshLoader in 'C:\Program Files (x86)\Embarcadero\Gen2_v1.4\G2MeshLoader.pas',
  DXTypes in 'C:\Program Files (x86)\Embarcadero\DirectX9\DXTypes.pas',
  Direct3D9 in 'C:\Program Files (x86)\Embarcadero\DirectX9\Direct3D9.pas',
  D3DX9 in 'C:\Program Files (x86)\Embarcadero\DirectX9\D3DX9.pas',
  DirectInput in 'C:\Program Files (x86)\Embarcadero\DirectX9\DirectInput.pas',

  cuFuncs in '..\..\_common\cuFuncs.pas',
  cuSimpleINI in '..\..\_common\cuSimpleINI.pas',
  cuSplitLine in '..\..\_common\cuSplitLine.pas',
  cuSplitFile in '..\..\_common\cuSplitFile.pas',
  cuZoom in '..\..\_common\cuZoom.pas',
  cuDebug in '..\..\_common\cuDebug.pas',
  cuSimpleArrays in '..\..\_common\cuSimpleArrays.pas',
  cuMath64 in '..\..\_common\cuMath64.pas',
  cuSorting in '..\..\_common\cuSorting.pas',
  cuVector in '..\..\_common\cuVector.pas',

  uAstro in 'uAstro.pas',
  uDefs in 'uDefs.pas',
  uUniverse in 'uUniverse.pas',
  uEmpire in 'uEmpire.pas',
  uBuildings in 'uBuildings.pas',
  uFleet in 'uFleet.pas',
  uStarLane in 'uStarLane.pas';

type
  TMyApp = class (TG2App)
  public
    MgrTextures : TG2TextureMgr;
    MgrFonts    : TG2FontMgr;
    Font1       : TG2Font;
    MainGUI     : TG2Texture2D;

    StarMap     : TG2Texture2DRT;
    MiniMap     : TG2Texture2DRT;
    ColonyMap   : TG2Texture2DRT;
    FleetMap    : TG2Texture2DRT;

    ClickPos    : TG2Vec2;
    tickTimer   : TTimer;

    Universe    : TUniverse;

    oldFPS,
    newFPS      : integer;
    procedure OnRender; override;
    procedure OnUpdate; override;
    procedure OnMouseDown(const Button: Byte); override;
    procedure OnKeyDown(const Key: Byte); override;
    procedure Initialize; override;
    procedure Finalize; override;

    procedure CreateStarMapTexture();
    procedure drawAstros(theWidth,theHeight:integer);
    procedure drawStarLanes();
    procedure CreateMiniMapTexture();
    procedure drawMinimap(theWidth,theHeight:integer);
    procedure CreateColonyMapTexture();
    procedure drawColonys();
    procedure CreateFleetMapTexture();
    procedure drawFleets();
    procedure drawSolarSystem(theSolarID:integer);
    procedure drawStats();

    procedure autoTicker(Sender:TObject);

    procedure errorCritical();
  end;

var
  App: TMyApp;

//TMyApp BEGIN
procedure TMyApp.OnRender;
var tickerColor:integer;
begin
  Render.Clear(False, False, True, $00000000);
  Render.RenderStart;

  oldFPS      := newFPS;
  newFPS      := tmr.FPS;

  if (oldFPS <> newFPS) then
  begin
    if (Tmr.FPS < Universe.uniBaseFPS)and(Universe.uniCurrentWeek > 10)and(tickTimer.Enabled) then
    begin
      if (tickTimer.Interval < 5000) then
        tickTimer.Interval := tickTimer.Interval + 1
      else
      begin
        DevConsole.Print(LOG_CRITICAL, '[TMyApp    ] LOW FPS WARNING.');
        tickTimer.Enabled := FALSE;
        DevConsole.saveLog();
      end;
    end;

    if (Tmr.FPS > Universe.uniBaseFPS)and(tickTimer.Enabled) then
    begin
      if (tickTimer.Interval > 2) then tickTimer.Interval := tickTimer.Interval - 1;
    end;
  end;

  if (Universe.m_updateAllMaps) then
  begin
    createStarMapTexture();
    createColonyMapTexture();
    createFleetMapTexture(); // needs to be auto updated
    Universe.updateAllMaps( FALSE );
  end;

  if (Universe.m_updateStarMap) then
  begin
    createStarMapTexture();
//    createStarLaneMapTexture();
  end;

  if (Universe.m_updateColonyMap) then
  begin
    createColonyMapTexture();
//    createMiniMapTexture();
  end;

  if (Universe.m_updateFleetMap) then
    createFleetMapTexture(); // needs to be auto updated

  Render2D.DrawRect(0, 0, StarMap);

  Render2D.DrawRect(0, 0, ColonyMap);

  Render2D.DrawRect(0, 0, FleetMap);

//  Render2D.DrawRect(15, 15, MainGUI);
//  Render2D.DrawRect(120, 120, MiniMap);

  drawStats();

  ClickPos := PlugInput.MousePos;

  RenderModes.FilteringPoint();
  if (tickTimer.Enabled) then
    tickerColor := $ffff0000
  else
    tickerColor := $ffffffff;

  Font1.Print(10,10, tickerColor, 'FPS: ' + IntToStr(Tmr.FPS)+', CurrentAge: '+FormatFloat('0.00', Universe.uniStartYear + WeeksToStarDate(Universe.uniCurrentWeek))+', Zoom: '+FormatFloat('0.00000',Universe.uniZoom.Value)+' Dialation: '+IntToStr(tickTimer.Interval) );

  Render.RenderStop;
  Render.Present;
end;

procedure TMyApp.OnUpdate;
begin

end;

procedure TMyApp.OnMouseDown(const Button: Byte);
begin
end;

procedure TMyApp.OnKeyDown(const Key: Byte);
var rand : integer;
begin
  case Key of
    DIK_ESCAPE : Running := False;
    DIK_RETURN : begin // AutoTicker
      tickTimer.Enabled := not tickTimer.Enabled;
      if (tickTimer.Enabled) then DevConsole.Print(LOG_DEBUG1, '[TMyApp] autoTicker Enabled')
      else                        DevConsole.Print(LOG_DEBUG1, '[TMyApp] autoTicker Disabled');
    end;
    DIK_SPACE    : begin Universe.Ticker(); Universe.updateAllMaps(); end;// SingleTick
    DIK_EQUALS   : begin Universe.uniZoom.ZoomIn();  Universe.updateAllMaps(); end;
    DIK_MINUS    : begin Universe.uniZoom.ZoomOut(); Universe.updateAllMaps(); end;
    DIK_BACK : begin
      Rand := Random(Universe.uniAIPlayers);
      Universe.createFleet( Universe.uniStarList.getItem( Rand ), rand );
      Universe.exportInfo();

      Universe.updateFleetMap();
    end;
    DIK_F12        : DevConsole.Clear();
    DIK_F1         : DevConsole.setLogLevel('1 2');
    DIK_F2         : DevConsole.setLogLevel('1 2 3');
    DIK_F3         : DevConsole.setLogLevel('1 2 3 4');
    DIK_F4         : DevConsole.setLogLevel('1 2 3 4 5');
    DIK_F5         : Universe.updateAllMaps();//Force refresh maybe? Rather than passive refresh.
    DIK_F6         : begin Universe.createEmpire(-1,''); Universe.updateAllMaps(); end;
    DIK_F7         : DevConsole.saveLog();
    DIK_F8         : DevConsole.Print(LOG_CRITICAL, '[TMyApp] critical debug test');
    DIK_RIGHTARROW : begin Universe.uniStart.moveRight(ceil((100*Universe.uniBlackSpace) / Universe.uniZoom.Value)); Universe.updateAllMaps(); end;
    DIK_LEFTARROW  : begin Universe.uniStart.moveLeft(ceil((100*Universe.uniBlackSpace) / Universe.uniZoom.Value)); Universe.updateAllMaps(); end;
    DIK_DOWNARROW  : begin Universe.uniStart.moveDown(ceil(100*Universe.uniBlackSpace / Universe.uniZoom.Value)); Universe.updateAllMaps(); end;
    DIK_UPARROW    : begin Universe.uniStart.moveUp(ceil(100*Universe.uniBlackSpace / Universe.uniZoom.Value)); Universe.updateAllMaps(); end;
    DIK_TAB        : begin with Universe do begin Universe.uniZoom.Value := 1; uniStart.setVector2D( round(uniResWidth/2)*uniBlackSpace, round(uniResHeight/2)*uniBlackSpace ); Universe.updateAllMaps(); end; end;
    DIK_Q          : begin Universe.New(); Universe.updateAllMaps(); end;
    DIK_Z          : begin with Universe do begin uniZoom.Value := 200; uniStart.setVector2D( getAstro(0).astroLocation.X,getAstro(0).astroLocation.Y ); updateAllMaps(); end; end;
    DIK_N          : begin universe.decreaseStarlanes(); Universe.uniStarLane.Clear(); Universe.createStarLanes1(); Universe.updateAllMaps(); end;
    DIK_M          : begin Universe.increaseStarLanes(); Universe.uniStarLane.Clear(); Universe.createStarLanes1(); Universe.updateAllMaps(); end;
  end;
end;

//Drawing textures
procedure TMyApp.CreateStarMapTexture();
begin
  DevConsole.Print(LOG_DEBUG2, '[TMyApp   ] CreateStarMapTexture()');

  Gfx.SetRenderTargetTexture2D( StarMap );

  Render.RenderStart;

  Render2D.DrawRect(0, 0, TG2Texture2D(MgrTextures.FindTexture('bg')) );

  drawStarLanes();

  drawAstros(0,0);

  Render.RenderStop;

  Gfx.SetRenderTargetDefault();//Goes back to back buffer

//  DevConsole.Print(ES_DEBUG, '[TMyApp] end - CreateStarMapTexture()');
end;
procedure TMyApp.drawAstros(theWidth,theHeight:integer);
var S, A, nX, nY, OffSet  : integer;
begin
  Offset := 16;

  with Universe do
  for S := 0 to uniStarList.Count-1 do
  begin
    A := uniStarList.getItem( S ); // 0 = always equals the star of the system

    with getAstro( A ) do
    begin
      astroLocation.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);

      nX := astroLocation.altX;
      nY := astroLocation.altY;

      case astroClimate of
        climateBLUESTAR   : Render2D.DrawRect(nX-Offset, nY-Offset, TG2Texture2D(MgrTextures.FindTexture('bluestar')));
        climateYELLOWSTAR : Render2D.DrawRect(nX-Offset, nY-Offset, TG2Texture2D(MgrTextures.FindTexture('yellowstar')));
        climateREDSTAR    : Render2D.DrawRect(nX-Offset, nY-Offset, TG2Texture2D(MgrTextures.FindTexture('redstar')));
      end;
    end;
  end;

  Universe.updateStarMap( FALSE );
end;
procedure TMyApp.drawStarLanes();
var L,Offset : integer; fromVector,toVector:TG2Vec2;
begin
  offSet:= 16;
  with Universe do
  for L := 0 to uniStarLane.Count-1 do
  begin
    with getStarLane( L ) do
    begin
      getAstro( startPoint ).astroLocation.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);
      getAstro( endPoint ).astroLocation.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);

      fromVector.SetValue( getAstro( startPoint ).astroLocation.altX, getAstro( startPoint ).astroLocation.altY );
      toVector.SetValue( getAstro( endPoint ).astroLocation.altX, getAstro( endPoint ).astroLocation.altY );

      Render.TextureClear();
//      DevConsole.Print(ES_DEBUG, 'TFleet: launchFleet.drawLine : '+FormatFloat('0.00',fromVector.X)+':'+FormatFloat('0.00',fromVector.Y)+' <--------> '+FormatFloat('0.00',toVector.X)+':'+FormatFloat('0.00',toVector.Y));
      Prim2D.DrawLine( fromVector, toVector, IntToColor( 30 ));
//      Render2D.DrawRect(fromVector.x, fromVector.y, TG2Texture2D(MgrTextures.FindTexture('colonized')));

//      RenderModes.FilteringPoint();
//      Font1.Print(fleetCurrentVector.altX+5, fleetCurrentVector.altY-Offset+5, IntToColor( fleetEmpireID ), IntToStr( fleetTimeLeft(uniCurrentWeek) ));
    end;
  end;

//  if (Universe.uniZoom.Value > 20) then

  Universe.updateFleetMap( FALSE );
end;
procedure TMyApp.CreateMiniMapTexture();
begin
  DevConsole.Print(LOG_DEBUG2, '[TMyApp   ] CreateMiniMapTexture()');

  Gfx.SetRenderTargetTexture2D( MiniMap );

  Render.RenderStart;

  drawMiniMap(200,200);

  Render.RenderStop;

  Gfx.SetRenderTargetDefault();//Goes back to back buffer

//  DevConsole.Print(ES_DEBUG, '[TMyApp] end - CreateStarMapTexture()');
end;
procedure TMyApp.drawMiniMap(theWidth,theHeight:integer);
var S, A  : integer;aLocation:TVector2D;centerVector:TG2Vec2;
begin
  aLocation := TVector2D.Create();

  with Universe do
  for S := 0 to uniStarList.Count-1 do
  begin
    A := uniStarList.getItem( S );

    with getAstro( A ) do
    begin
      aLocation.setVector2D( astroLocation.X, astroLocation.Y );

      aLocation.resizeToResolution2D( 1280, 720, 800, 800);

      aLocation.X:= round(aLocation.X*(40/theWidth));
      aLocation.Y:= round(aLocation.Y*(40/theHeight));

      Render.TextureClear();
      centerVector.SetValue( aLocation.X, aLocation.Y );

      Prim2D.DrawCircleHollow(centerVector, 0, 1, IntToColor( astroEmpireID, TRUE ) );
    end;
  end;
  FreeAndNil( aLocation );
//  Universe.updateMiniMap := FALSE;
end;
procedure TMyApp.CreateColonyMapTexture();
begin
  DevConsole.Print(LOG_DEBUG2, '[TMyApp   ] CreateColonyMapTexture()');

  Gfx.SetRenderTargetTexture2D( ColonyMap );

  Render.Clear(False, False, True, $00000000);
  Render.RenderStart;

  drawColonys();

  Render.RenderStop;

  Gfx.SetRenderTargetDefault();//Goes back to back buffer
end;
procedure TMyApp.drawColonys();
var S, A, nX, nY, OffSet : integer;centerVector:TG2Vec2; innerOffset,outerOffset:real;
begin
  Offset := 28;

  with Universe do
  for S := 0 to uniStarList.Count-1 do
  begin
    A := uniStarList.getItem( S ); // 0 = always equals the star of the system

    with getAstro( A ) do
    begin
      astroLocation.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);

      nX := astroLocation.altX;
      nY := astroLocation.altY;

      if (astroEmpireID > -1) then
      begin
        Render.TextureClear();
        centerVector.SetValue( nX, nY );

        innerOffSet := 2*uniZoom.Value;
        outerOffSet := 2.5*uniZoom.Value;

        Prim2D.DrawCircleHollow(centerVector, 5+innerOffSet, 6+outerOffset, IntToColor( astroEmpireID ));

        RenderModes.FilteringPoint();
        if (astroFleetsInOrbit > 0) then
        begin
          if (astroFleetsInOrbit < 2) then
            Render2D.DrawRect(nX-Offset, nY-Offset, TG2Texture2D(MgrTextures.FindTexture('smallfleet')))
          else
          if (astroFleetsInOrbit < 3) then
            Render2D.DrawRect(nX-Offset, nY-Offset, TG2Texture2D(MgrTextures.FindTexture('mediumfleet')))
          else
            Render2D.DrawRect(nX-Offset, nY-Offset, TG2Texture2D(MgrTextures.FindTexture('largefleet')));
        end;
      end;
    end;

    drawSolarSystem( S );
  end;

  with Universe do
  for S := 0 to uniStarList.Count-1 do
  begin
    A := uniStarList.getItem( S ); // 0 = always equals the star of the system

    with getAstro( A ) do
    begin
      astroLocation.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);

      nX := astroLocation.altX;
      nY := astroLocation.altY;

      if (uniZoom.Value > 10) then
        Font1.Print(nX+15, nY-10, $ffffffff, astroName+' ('+IntToStr(astroGrowth)+', '+IntToStr(astroMaxPopulation)+')' );
    end;
  end;

  Universe.updateColonyMap( FALSE );
end;
procedure TMyApp.drawSolarSystem(theSolarID:integer);
var A,P,nX,nY : integer; planetList:TIntegerArray; centerVector:TG2Vec2; newLocation:TVector2D;
begin
  newLocation := TVector2D.Create();

  if (floor(Universe.uniZoom.Value/20) <= 0) then exit;

  with Universe do
  begin
    A := uniStarList.getItem( theSolarID ); // 0 = always equals the star of the system

    planetList:= findOrbittingAstros(A);

    for P := 0 to planetList.Count-1 do
    begin
      with getAstro( planetList.getItem(P) ) do
      begin
        Render.TextureClear();

        nX := getAstro(A).astroLocation.X + astroLocation.X;;
        nY := getAstro(A).astroLocation.Y + astroLocation.Y;;

        newLocation.setVector2D(nX, nY);
        newLocation.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);

        nX := newLocation.altX;
        nY := newLocation.altY;

        with Universe do
        if (nX < 0)or(nX > uniResWidth)or(nY < 0)or(nY > uniResHeight) then Continue;

        centerVector.SetValue( nX, nY );

        case astroClimate of
          climateDESERT :Prim2D.DrawCircle(centerVector, round(astroSize+(uniZoom.Value/100)), IntToColor( 1 ));
          climateGAS    :Prim2D.DrawCircle(centerVector, round(astroSize+(uniZoom.Value/100)), IntToColor( 3 ));
          climateGAIA   :Prim2D.DrawCircle(centerVector, round(astroSize+(uniZoom.Value/100)), IntToColor( 0 ));
          climateOCEAN  :Prim2D.DrawCircle(centerVector, round(astroSize+(uniZoom.Value/100)), IntToColor( 2 ));
          climateICE    :Prim2D.DrawCircle(centerVector, round(astroSize+(uniZoom.Value/100)), IntToColor( 32 ));
        end;

        if (uniZoom.Value > 100) then
          Font1.Print(nX+15, nY-10, $ffffffff, astroName+' ('+IntToStr(astroGrowth)+')' );
      end;
    end;
  end;
  FreeAndNil( newLocation );
  FreeAndNil( planetList );
end;
procedure TMyApp.CreateFleetMapTexture();
begin
  DevConsole.Print(LOG_DEBUG2, '[TMyApp   ] CreateFleetMapTexture()');

  Gfx.SetRenderTargetTexture2D( FleetMap );

  Render.Clear(False, False, True, $00000000);
  Render.RenderStart;

  drawFleets();

  Render.RenderStop;

  Gfx.SetRenderTargetDefault();//Goes back to back buffer

//  DevConsole.Print(ES_DEBUG, '[TMyApp] end - CreateFleetMapTexture()');
end;
procedure TMyApp.drawFleets();
var F,Offset : integer; fromVector,toVector:TG2Vec2;
begin
  offSet:= 16;
  with Universe do
  for F := 0 to uniFleet.Count-1 do
  begin
    with getFleet( F ) do
    begin
      if (getEmpire( fleetEmpireID ).empireDead) then Continue;

      if ( fleetInOrbit() ) then Continue;

      fleetCurrentVector.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);
      fleetStartVector.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);
      fleetEndVector.fitToScreen(uniStart.X, uniStart.Y, uniBlackspace, uniZoom.Value);

      Render2D.DrawRect(fleetCurrentVector.altX-OffSet, fleetCurrentVector.altY-OffSet, TG2Texture2D(MgrTextures.FindTexture('smallfleet')));

      fromVector.SetValue( fleetCurrentVector.altX, fleetCurrentVector.altY );
      toVector.SetValue( fleetEndVector.altX, fleetEndVector.altY );

      Render.TextureClear();
//      DevConsole.Print(ES_DEBUG, 'TFleet: launchFleet.drawLine : '+FormatFloat('0.00',fromVector.X)+':'+FormatFloat('0.00',fromVector.Y)+' <--------> '+FormatFloat('0.00',toVector.X)+':'+FormatFloat('0.00',toVector.Y));
      Prim2D.DrawLine( fromVector, toVector, IntToColor( fleetEmpireID ));

      RenderModes.FilteringPoint();
      Font1.Print(fleetCurrentVector.altX+5, fleetCurrentVector.altY-Offset+5, IntToColor( fleetEmpireID ), IntToStr( fleetTimeLeft(uniCurrentWeek) ));
    end;
  end;

//  if (Universe.uniZoom.Value > 20) then

  Universe.updateFleetMap( FALSE );
end;
procedure TMyApp.drawStats();
var E, OffSet : integer;Percent : real;
begin
  OffSet := 0;
  with Universe do
  begin
    Render.TextureClear();
    Prim2D.DrawRect( 890, 1, 400, 720, $99000000);
    for E := 0 to uniEmpire.Count-1 do
    begin
      if (getEmpire( E ).empireDead) then Continue;

      Font1.Print(900, 690-OffSet, IntToColor( E ), IntToAlpha( E )+': '+IntToStr( getEmpire(E).empirePopulation )+' ('+IntToStr( getEmpire(E).empireMaxPopulation )+')'+
                                                        ' Planets: '+IntToStr(getEmpire(E).empireAstro.Count)+
                                                        ' Fleets: '+IntToStr(getEmpire(E).empireFleet.Count)+
                                                        ' Growth: '+IntToStr(getEmpire(E).empireTotalGrowth));
      //BarChart
      Render.TextureClear();

      if (uniCurrentWeek > 0) then
      with getEmpire( E ) do
      begin
        Percent := ( empirePopulation / empireMaxPopulation );
        Prim2D.DrawRect( 1270-OffSet, 100, 5, round( 300*Percent), IntToColor( E ));
        Prim2D.DrawRectHollow( 1270-OffSet, 100, 5, 300, $ff999999 );

        Percent := ( empirePopulation / uniPopulation );
        Prim2D.DrawRect( 1270-Offset-7, 100, 5, round( 500*Percent), IntToColor(e));

        Percent := ( empireMaxPopulation / uniMaxPopulation );
        Prim2D.DrawRectHollow( 1270-OffSet-7, 100, 5, round( 500*Percent), $ff999999 {IntegerToColor(e)});
        //end
      end;
      Inc( OffSet, 18 );
    end;
  end;
end;

procedure TMyApp.Initialize;
begin
  Randomize;

  DevConsole := TDebugConsole.Create(GameName+' / '+Copyright+' / '+Version);
  DevConsole.setLogLevel('1 2 3 4 5 7');

  Universe := TUniverse.Create();

  with Universe do
  begin
    SimpleINI := TSimpleINI.Create();
    SimpleINI.Load('settings.ini');
    DevConsole.SetLogLevel( SimpleINI.sFind('sDebug') );

    Gfx.InitParams.Width := SimpleINI.iFind('iScreenWidth');
    Gfx.InitParams.Height := SimpleINI.iFind('iScreenHeight');
    Gfx.InitParams.FullScreen := SimpleINI.bFind('bFullscreen');
  end;

  Gfx.InitParams.FormatBackBuffer := D3DFMT_A8R8G8B8;
  Gfx.InitParams.FormatSurfaceRT := D3DFMT_A8R8G8B8;
  Gfx.InitParams.FormatSurfaceDS := D3DFMT_D16;
  g2.Handle := App.WindowCreate(Gfx.InitParams.Width, Gfx.InitParams.Height, 'Blackspace - Alpha');
  Tmr.Mode := tmManual;
  Tmr.MaxFPS := 0;
  inherited Initialize;
  g2.RequestMod(TG2TextureMgr, @MgrTextures);
  g2.RequestMod(TG2FontMgr, @MgrFonts);
  Font1 := Gfx.Shared.RequestFont('Times New Roman', 12);

  MainGUI   := MgrTextures.CreateTexture2DFromFile('gamegui', GetEXEPath+'images\gui\game_gui.png');
  StarMap   := MgrTextures.CreateTexture2DRT('RT1', 2048, 2048);
  MiniMap   := MgrTextures.CreateTexture2DRT('RT2', 256 , 256);
  ColonyMap := MgrTextures.CreateTexture2DRT('RT3', 2048, 2048);
  FleetMap  := MgrTextures.CreateTexture2DRT('RT4', 2048, 2048);

  MgrTextures.CreateTexture2DFromFile('ship'       , 'images\ships\ship.png'              );
  MgrTextures.CreateTexture2DFromFile('smallfleet' , 'images\ships\f_smallfleet.png'      );
  MgrTextures.CreateTexture2DFromFile('mediumfleet', 'images\ships\f_mediumfleet.png'     );
  MgrTextures.CreateTexture2DFromFile('largefleet' , 'images\ships\f_largefleet.png'      );
  MgrTextures.CreateTexture2DFromFile('colonized'  , 'images\gui\colonized.png'           );
  MgrTextures.CreateTexture2DFromFile('bg'         , 'images\galaxy\bg.png'               );

  MgrTextures.CreateTexture2DFromFile('desert'   , 'images\astros\p_smalldesert.png'  );
  MgrTextures.CreateTexture2DFromFile('gas'      , 'images\astros\p_smallgas.png'     );
  MgrTextures.CreateTexture2DFromFile('gaia'     , 'images\astros\p_smallgaia.png'  );
  MgrTextures.CreateTexture2DFromFile('ocean'    , 'images\astros\p_smallocean.png'  );
  MgrTextures.CreateTexture2DFromFile('ice'      , 'images\astros\p_smallice.png'  );

  MgrTextures.CreateTexture2DFromFile('bluestar'   , 'images\astros\s_smallbluestar.png'  );
  MgrTextures.CreateTexture2DFromFile('redstar'    , 'images\astros\s_smallredstar.png'   );
  MgrTextures.CreateTexture2DFromFile('yellowstar' , 'images\astros\s_smallyellowstar.png');
  MgrTextures.CreateTexture2DFromFile('orangestar' , 'images\astros\s_smallorangestar.png');

  Universe.New();

  oldFPS      := 0;
  newFPS      := 0;

//  DevConsole.modeBuffer( TRUE ); //Writes to the Buffer

//  DevConsole.runOnCritical := errorCritical;

  tickTimer := TTimer.Create(nil);
  tickTimer.Interval := 40;
  tickTimer.OnTimer := autoTicker;
  tickTimer.Enabled := FALSE;

  DevConsole.saveLog();

  Tmr.Enabled := True;
end;
procedure TMyApp.Finalize;
begin
  inherited Finalize;
end;
procedure TMyApp.autoTicker(Sender:TObject);
begin
//  Universe.uniZoom.AutoZoom();

  DevConsole.clearBuffer(); //no errors so carry on.
  try
    with Universe do
      Ticker();
  except
    on E : Exception do
    begin
      DevConsole.Print(LOG_CRITICAL, '[TMyApp   ] Exception message = '+E.Message);
      DevConsole.SaveLog();
    end;
  end;

  if ( DevConsole.hasCritical ) then
  begin
    DevConsole.SaveLog();
    tickTimer.Enabled := FALSE;
    DevConsole.resetError();
  end;

  Universe.updateColonyMap();
end;
procedure TMyApp.errorCritical;
begin
  tickTimer.Enabled := FALSE;
end;
//TMyApp END

begin
  App := TMyApp.Create;
  App.Initialize;
  if App.g2.Initialized then
  try
    App.Loop;
  except
    on E : Exception do
    begin
      DevConsole.Print(LOG_CRITICAL, '[TMyApp   ] Exception message = '+E.Message);
      DevConsole.SaveLog();
      App.Free;
    end;
  end;
  App.Free;
  ExitCode := 0;
end.
